python
import tkinter as tk
import time
class PongGame:
def __init__(self, root):
self.root = root
self.root.title("Pong Game")
self.width = 800
self.height = 400
self.paddle_width = 10
self.paddle_height = 100
self.ball_size = 20
self.ball_speed = 5
self.paddle_speed = 20
self.ball_speed_increment = 0.05
self.game_duration = 30
self.left_score = 0
self.right_score = 0
self.canvas = tk.Canvas(root, width=self.width, height=self.height, bg="black")
self.canvas.pack()
self.canvas.create_line(self.width/2, 0, self.width/2, self.height, fill="white")
self.left_paddle = self.canvas.create_rectangle(
10, (self.height - self.paddle_height)/2,
10 + self.paddle_width, (self.height + self.paddle_height)/2,
fill="white"
)
self.right_paddle = self.canvas.create_rectangle(
self.width - 10 - self.paddle_width, (self.height - self.paddle_height)/2,
self.width - 10, (self.height + self.paddle_height)/2,
fill="white"
)
self.ball = self.canvas.create_oval(
(self.width - self.ball_size)/2, (self.height - self.ball_size)/2,
(self.width + self.ball_size)/2, (self.height + self.ball_size)/2,
fill="white"
)
self.left_paddle_move = 0
self.right_paddle_move = 0
self.ball_dx = self.ball_speed
self.ball_dy = self.ball_speed
self.root.bind("w", self.move_left_paddle_up)
self.root.bind("s", self.move_left_paddle_down)
self.root.bind("<Up>", self.move_right_paddle_up)
self.root.bind("<Down>", self.move_right_paddle_down)
self.game_over = False
self.start_time = time.time()
self.left_score_text = self.canvas.create_text(self.width/4, 20, text=f"{self.left_score}", font=("Arial", 24), fill="white")
self.right_score_text = self.canvas.create_text(3*self.width/4, 20, text=f"{self.right_score}", font=("Arial", 24), fill="white")
self.game_loop()
def move_left_paddle_up(self, event):
self.left_paddle_move = -self.paddle_speed
def move_left_paddle_down(self, event):
self.left_paddle_move = self.paddle_speed
def move_right_paddle_up(self, event):
self.right_paddle_move = -self.paddle_speed
def move_right_paddle_down(self, event):
self.right_paddle_move = self.paddle_speed
def game_loop(self):
if not self.game_over:
self.move_paddles()
self.move_ball()
elapsed_time = time.time() - self.start_time
if elapsed_time >= self.game_duration:
self.end_game()
else:
self.ball_dx *= (1 + self.ball_speed_increment/100)
self.ball_dy *= (1 + self.ball_speed_increment/100)
self.root.after(20, self.game_loop)
def move_paddles(self):
self.canvas.move(self.left_paddle, 0, self.left_paddle_move)
left_paddle_pos = self.canvas.coords(self.left_paddle)
if left_paddle_pos[1] < 0:
self.canvas.move(self.left_paddle, 0, -left_paddle_pos[1])
elif left_paddle_pos[3] > self.height:
self.canvas.move(self.left_paddle, 0, self.height - left_paddle_pos[3])
self.left_paddle_move = 0
self.canvas.move(self.right_paddle, 0, self.right_paddle_move)
right_paddle_pos = self.canvas.coords(self.right_paddle)
if right_paddle_pos[1] < 0:
self.canvas.move(self.right_paddle, 0, -right_paddle_pos[1])
elif right_paddle_pos[3] > self.height:
self.canvas.move(self.right_paddle, 0, self.height - right_paddle_pos[3])
self.right_paddle_move = 0
def move_ball(self):
self.canvas.move(self.ball, self.ball_dx, self.ball_dy)
ball_pos = self.canvas.coords(self.ball)
if ball_pos[1] <= 0 or ball_pos[3] >= self.height:
self.ball_dy = -self.ball_dy
if self.check_paddle_collision(self.left_paddle, ball_pos):
self.ball_dx = abs(self.ball_dx)
if self.check_paddle_collision(self.right_paddle, ball_pos):
self.ball_dx = -abs(self.ball_dx)
if ball_pos[0] <= 0:
self.right_score += 1
self.update_score()
self.animate_score("Right Player Scores!")
self.reset_ball()
if ball_pos[2] >= self.width:
self.left_score += 1
self.update_score()
self.animate_score("Left Player Scores!")
self.reset_ball()
def check_paddle_collision(self, paddle, ball_pos):
paddle_pos = self.canvas.coords(paddle)
if (ball_pos[2] >= paddle_pos[0] and ball_pos[0] <= paddle_pos[2]) and \
(ball_pos[3] >= paddle_pos[1] and ball_pos[1] <= paddle_pos[3]):
return True
return False
def reset_ball(self):
self.canvas.coords(
self.ball,
(self.width - self.ball_size)/2, (self.height - self.ball_size)/2,
(self.width + self.ball_size)/2, (self.height + self.ball_size)/2
)
self.ball_dx = -self.ball_dx
self.ball_dy = self.ball_speed if self.ball_dy > 0 else -self.ball_speed
def update_score(self):
self.canvas.itemconfig(self.left_score_text, text=f"{self.left_score}")
self.canvas.itemconfig(self.right_score_text, text=f"{self.right_score}")
def animate_score(self, message):
text = self.canvas.create_text(self.width/2, self.height/2, text=message, font=("Arial", 36), fill="yellow")
self.root.update()
time.sleep(1)
self.canvas.delete(text)
def end_game(self):
self.game_over = True
winner = "Left Player Wins!" if self.left_score > self.right_score else "Right Player Wins!" if self.right_score > self.left_score else "It's a Tie!"
self.canvas.create_text(self.width/2, self.height/2 - 30, text="Game Over", font=("Arial", 48), fill="red")
self.canvas.create_text(self.width/2, self.height/2 + 30, text=winner, font=("Arial", 36), fill="white")
replay_button = tk.Button(self.root, text="Replay", command=self.restart_game)
self.canvas.create_window(self.width/2, self.height/2 + 80, window=replay_button)
def restart_game(self):
self.left_score = 0
self.right_score = 0
self.update_score()
self.reset_ball()
self.canvas.coords(
self.left_paddle,
10, (self.height - self.paddle_height)/2,
10 + self.paddle_width, (self.height + self.paddle_height)/2
)
self.canvas.coords(
self.right_paddle,
self.width - 10 - self.paddle_width, (self.height - self.paddle_height)/2,
self.width - 10, (self.height + self.paddle_height)/2
)
self.canvas.delete("all")
self.canvas.create_line(self.width/2, 0, self.width/2, self.height, fill="white")
self.left_paddle = self.canvas.create_rectangle(
10, (self.height - self.paddle_height)/2,
10 + self.paddle_width, (self.height + self.paddle_height)/2,
fill="white"
)
self.right_paddle = self.canvas.create_rectangle(
self.width - 10 - self.paddle_width, (self.height - self.paddle_height)/2,
self.width - 10, (self.height + self.paddle_height)/2,
fill="white"
)
self.ball = self.canvas.create_oval(
(self.width - self.ball_size)/2, (self.height - self.ball_size)/2,
(self.width + self.ball_size)/2, (self.height + self.ball_size)/2,
fill="white"
)
self.left_score_text = self.canvas.create_text(self.width/4, 20, text=f"{self.left_score}", font=("Arial", 24), fill="white")
self.right_score_text = self.canvas.create_text(3*self.width/4, 20, text=f"{self.right_score}", font=("Arial", 24), fill="white")
self.ball_dx = self.ball_speed
self.ball_dy = self.ball_speed
self.game_over = False
self.start_time = time.time()
self.game_loop()
if __name__ == "__main__":
root = tk.Tk()
game = PongGame(root)
root.mainloop()
This code creates a two-player Pong game using Python's built-in tkinter
module. It includes:
- Graphics: The game window displays paddles, a ball, and a center line on a canvas.
- Controls:
- Left player uses the
W
(up) and S
(down) keys. - Right player uses the
Up Arrow
(up) and Down Arrow
(down) keys.
- Scoring and Animation: When a player scores, an animation displays a message for a short duration.
- Timer: Each round lasts 30 seconds, after which the game ends, and a replay button appears.
- Ball Speed Increase: The ball gradually speeds up over time.
To run the game, save the code in a file named pong_game.py
and execute it with Python 3.12:
bash
python3.12 pong_game.py